﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace LevelEditor
{
	public partial class frmMainForm : Form
	{
		const int TimelineWidthOffset = 30;
		const int DefaultLevelTime = 200;
		int lastLevelTime = DefaultLevelTime;
		string currentLevelFilename = string.Empty;
		string baseFormText;
		bool hasChanged;

		public frmMainForm()
		{
			InitializeComponent();
			baseFormText = Text;

			// تعداد كافة النماذج المتوفرة للعبة
			//cboSelectLevelTube.Items.Add(currentLevel.LevelTubeModel);

			UpdateTitle();
		}

		EventTimeline AddEventTimelineControl(bool isRanged, int totalTime)
		{
			EventTimeline newEvent = new EventTimeline(isRanged, totalTime);
			newEvent.Width = flwEventsPanel.Width - TimelineWidthOffset;
			newEvent.Deleted += new EventHandler(OnEventDeleted);
			newEvent.StartTime = 0;
			if (isRanged)
				newEvent.EndTime = 5;
			flwEventsPanel.Controls.Add(newEvent);
			return newEvent;
		}

		void OnLevelChanged()
		{
			if (hasChanged)
				return;
			hasChanged = true;
			UpdateTitle();
		}

		bool ConfirmLoseChanges()
		{
			if (!hasChanged)
				return true;
			var result = MessageBox.Show(this, "جرت بعض التعديلات على المرحلة الحالية ولم يتم حفظها بعد.\nهل ترغب بحفظ هذه التعديلات قبل الاستمرار؟",
				"حفظ التعديلات...", MessageBoxButtons.YesNoCancel,
				MessageBoxIcon.Question, MessageBoxDefaultButton.Button1,
				MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);

			if (result == DialogResult.Yes)
			{
				btnSave_Click(null, null);
				return true;
			}
			else if (result == DialogResult.No)
				return true;
			return false;
		}

		void UpdateTitle()
		{
			Text = baseFormText;
			string fileTitle = string.IsNullOrEmpty(currentLevelFilename) ? "مرحلة جديدة" :
				(new System.IO.FileInfo(currentLevelFilename).Name);

			Text += " (" + fileTitle + ")";
			if (hasChanged)
				Text += " *";
		}

		#region Events
		void OnEventDeleted(object sender, EventArgs e)
		{
			flwEventsPanel.Controls.Remove((EventTimeline)sender);
			OnLevelChanged();
		}

		private void btnNew_Click(object sender, EventArgs e)
		{
			if (!ConfirmLoseChanges())
				return;

			txtLevelName.Text = string.Empty;
			if (cboSelectLevelTube.Items.Count > 0)
				cboSelectLevelTube.SelectedIndex = 0;
			txtLevelTotalTime.Text = DefaultLevelTime.ToString();
			flwEventsPanel.Controls.Clear();
			lastLevelTime = DefaultLevelTime;
			currentLevelFilename = string.Empty;
			hasChanged = false;
			UpdateTitle();
		}

		private void btnNewPeriodEvent_Click(object sender, EventArgs e)
		{
			int time = (int)Convert.ToUInt32(txtLevelTotalTime.Text);
			flwEventsPanel.ScrollControlIntoView(AddEventTimelineControl(true, time));
			OnLevelChanged();
		}

		private void btnNewInstantEvent_Click(object sender, EventArgs e)
		{
			int time = (int)Convert.ToUInt32(txtLevelTotalTime.Text);
			flwEventsPanel.ScrollControlIntoView(AddEventTimelineControl(false, time));
			OnLevelChanged();
		}

		private void flwEventsPanel_ClientSizeChanged(object sender, EventArgs e)
		{
			foreach (Control c in flwEventsPanel.Controls)
				c.Width = flwEventsPanel.Width - TimelineWidthOffset;
			flwEventsPanel.PerformLayout();
		}

		private void txtLevelTotalTime_Leave(object sender, EventArgs e)
		{
			int levelTime;
			try
			{
				levelTime = Convert.ToInt32(txtLevelTotalTime.Text);
				if (levelTime < 5)
					throw new Exception();
			}
			catch
			{
				MessageBox.Show("يرجى تحديد الزمن بالثواني كرقم صحيح يتجاوز الخمس ثواني", "خطأ في إدخال الزمن", MessageBoxButtons.OK, MessageBoxIcon.Warning);
				txtLevelTotalTime.Focus();
				return;
			}

			if (lastLevelTime == levelTime)
				return; // لا تعديلات

			if (flwEventsPanel.Controls.Count > 0)
			{
				DialogResult result = MessageBox.Show(
					"هل ترغب بإعادة توزيع الأحداث بالتناسب مع الفترة الزمنية الجديدة؟\nالأحداث خارج الزمن الجديد سيتم حدها إن لم تتم إعادة توزيعها بالتناسب...",
					 "إعادة توزيع الأحداث", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);
				if (result == DialogResult.Cancel)
				{
					txtLevelTotalTime.Text = lastLevelTime.ToString();
					return;
				}

				// ضبط أطوال كافة أشرطة الزمن
				bool rescaleTime = result == DialogResult.Yes;
				foreach (Control ctl in flwEventsPanel.Controls)
				{
					EventTimeline timeline = ctl as EventTimeline;
					if (timeline != null)
						timeline.SetLength(levelTime, rescaleTime);
				}
			}
			lastLevelTime = levelTime;
			OnLevelChanged();
		}

		private void btnSaveAs_Click(object sender, EventArgs e)
		{
			if (saveFileDialog.ShowDialog() != DialogResult.OK)
				return;
			currentLevelFilename = saveFileDialog.FileName;
			btnSave_Click(sender, e);
		}

		private void btnSave_Click(object sender, EventArgs e)
		{
			if (string.IsNullOrEmpty(currentLevelFilename))
			{
				btnSaveAs_Click(sender, e);
				if (string.IsNullOrEmpty(currentLevelFilename))
					return;
			}

			// إنشاء بنية بيانات المرحلة، وتعبئتها من التحكمات البصرية
			Sudum.LevelData level = new Sudum.LevelData();
			level.Name = txtLevelName.Text;
			if (cboSelectLevelTube.SelectedItem != null)
				level.Model = cboSelectLevelTube.SelectedItem.ToString();
			else level.Model = string.Empty;
			level.TimeSecs = (int)UInt32.Parse(txtLevelTotalTime.Text);

			foreach (Control ctl in flwEventsPanel.Controls)
			{
				EventTimeline timeline = ctl as EventTimeline;
				if (timeline == null)
					continue;
				Sudum.EventData eventData = new Sudum.EventData();
				eventData.Event = timeline.EventType;
				eventData.IsRanged = timeline.Ranged;
				eventData.SpawnCount = timeline.SpawnCount;
				eventData.StartTime = timeline.StartTime;
				eventData.EndTime = timeline.EndTime;
				level.Events.Add(eventData);
			}

			level.Save(currentLevelFilename);
			hasChanged = false;
			UpdateTitle();
		}

		private void btnOpen_Click(object sender, EventArgs e)
		{
			openFileDialog.FileName = string.Empty;
			if (openFileDialog.ShowDialog() != DialogResult.OK)
				return;

			if (!ConfirmLoseChanges())
				return;

			Sudum.LevelData level = new Sudum.LevelData();
			level.Load(openFileDialog.FileName);

			flwEventsPanel.Controls.Clear();
			txtLevelName.Text = level.Name;
			if (!string.IsNullOrEmpty(level.Model))
				cboSelectLevelTube.SelectedText = level.Model;
			txtLevelTotalTime.Text = level.TimeSecs.ToString();

			foreach (var evt in level.Events)
			{
				EventTimeline timeline = AddEventTimelineControl(evt.IsRanged, level.TimeSecs);
				timeline.EndTime = evt.EndTime;
				timeline.StartTime = evt.StartTime;
				timeline.SpawnCount = evt.SpawnCount;
				timeline.EventType = evt.Event;
			}

			currentLevelFilename = openFileDialog.FileName;
			hasChanged = false;
			UpdateTitle();
		}

		private void txtLevelName_TextChanged(object sender, EventArgs e)
		{
			OnLevelChanged();
		}

		private void frmMainForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (!ConfirmLoseChanges())
				e.Cancel = true;
		}
		#endregion
	}
}
